package org.cqust.backend.config.advice;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.servlet.http.HttpServletResponse;
import org.cqust.backend.common.ApiResult;
import org.cqust.backend.exception.BusinessException;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.io.IOException;

@Hidden
@ControllerAdvice
public class GlobalExceptionAdvice extends ResponseEntityExceptionHandler {
    private final ObjectMapper objectMapper = new ObjectMapper();

    //对于任何运行时错误，统一返回ApiResponse格式的数据
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ApiResult<?>> handleException(Exception ex, HttpServletResponse response) throws IOException {
        ApiResult<?> apiResult = ApiResult.error(HttpStatus.INTERNAL_SERVER_ERROR, "Internal Server Error: " + ex.getLocalizedMessage());
        return new ResponseEntity<>(apiResult, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    // BusinessException将在运行时，由代码手动抛出，用于指示数据不准确（缺少、意外等情况）
    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<ApiResult<?>> handleSpecificBusinessException(BusinessException ex, HttpServletResponse response) throws IOException {
        ApiResult<?> apiResult = ApiResult.error(ex.getLocalizedMessage());
        return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
    }


    // 处理AuthenticationException
    @ExceptionHandler(AuthenticationException.class)
    public ResponseEntity<ApiResult<?>> handleAuthenticationException(AuthenticationException ex, HttpServletResponse response) throws IOException {
        ApiResult<?> apiResult = ApiResult.error(HttpStatus.UNAUTHORIZED, "未登录: " + ex.getLocalizedMessage());
        return new ResponseEntity<>(apiResult, HttpStatus.UNAUTHORIZED);
    }

    // 处理AccessDeniedException
    @ExceptionHandler(AccessDeniedException.class)
    public ResponseEntity<ApiResult<?>> handleAccessDeniedException(AccessDeniedException ex, HttpServletResponse response) throws IOException {
        ApiResult<?> apiResult = ApiResult.error(HttpStatus.FORBIDDEN, "无权限: " + ex.getLocalizedMessage());
        return new ResponseEntity<>(apiResult, HttpStatus.FORBIDDEN);
    }

}
